package typejump.commands;

import java.lang.reflect.Method;

import typejump.Messenger;
import typejump.TypeJump;
import typejump.engine.GameEngine;
import typejump.engine.OnGoingThing;
import typejump.objects.GameObject;

/**
 * This is the TextCommand which is used for all the GameObject spawning
 * @author g
 *
 */
public class DevSpawnObject implements TextCommand, OnGoingThing {

	private String prefix;
	private GameObject[] objects;
	private double[] vx;
	private double[] vy;
	
	private Method createMethod = null;
	
	public DevSpawnObject(Class template, String prefix) {
		this(prefix);
		try {
			createMethod = template.getMethod("createObject", String.class);
		} catch (Exception e) {
			System.err.println("Illegal class - does not have a static createObject method");
		}
	}
	
	public DevSpawnObject(String prefix) {
		prefix = prefix.toLowerCase();
		this.prefix = "dev spawn " + prefix;
	}
	
	@Override
	public boolean matches(String command) {
		command = command.toLowerCase();
		return command.equals(prefix) || command.startsWith(prefix + " ");
	}
	
	@Override
	public boolean happen(TypeJump tj, double seconds) {
		if (objects == null) return true;
		
		for (int i = 0; i < objects.length; i++) {
			objects[i].left(tj.getSnappy(tj.getMouseX() - objects[i].width()/2));
			objects[i].top(tj.getSnappy(tj.getMouseY() - objects[i].height()/2));
			objects[i].vx(this.vx[i]);
			objects[i].vy(this.vy[i]);
		}
		
		
		if (Messenger.consumeMessage("mouse click")) {
			objects = null;
			return true;
		}
		return false;
	}

	
	private GameObject invokeCreateMethod(String params) {
		if (createMethod == null) return null;
		try {
			Object o = createMethod.invoke(null, params);
			if (o instanceof GameObject)
				return (GameObject)o;
		} catch (Exception e) {
			System.err.println(e + ": " + e.getMessage());
		}
		return null;
	}

	@Override
	public void act(String command) {
		command = command.substring(prefix.length()).trim();
		
		String[] params = null;
		if (command.contains("|")) {
			params = command.split("[|]");
			command = params[0];
		}
		
		int count = 1;
		if (command.matches("\\*\\s*[1-9]\\d*")) {
			int pos = command.lastIndexOf('*');
			count = Integer.parseInt(command.substring(pos+1).trim());
			command = command.substring(0, pos).trim();
		}
		
		objects = new GameObject[count];
		vx = new double[count];
		vy = new double[count];
		
		for (int i = 0; i < count; i++) {
			if (createMethod == null)
				objects[i] = createObject(command);
			else
				objects[i] = invokeCreateMethod(command);
			
			objects[i].centerX(TypeJump.getInst().getMouseX());
			objects[i].centerY(TypeJump.getInst().getMouseY());
			
			vx[i] = objects[i].vx();
			vy[i] = objects[i].vy();
			
			GameEngine.addObject(objects[i]);
		}
		
		GameEngine.addOnGoingThing(this);
		GameEngine.addTextEffect(prefix.toUpperCase(), "dev");
	}

	public GameObject createObject(String params) { return invokeCreateMethod(params); }
}
